{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# Creating a GeoDataFrame from a DataFrame with coordinates\n",
    "\n",
    "This example shows how to create a ``GeoDataFrame`` when starting from\n",
    "a *regular* ``DataFrame`` that has coordinates either WKT\n",
    "([well-known text](https://en.wikipedia.org/wiki/Well-known_text))\n",
    "format, or in\n",
    "two columns.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import geopandas\n",
    "import matplotlib.pyplot as plt\n",
    "from geodatasets import get_path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From longitudes and latitudes\n",
    "=============================\n",
    "\n",
    "First, let's consider a ``DataFrame`` containing cities and their respective\n",
    "longitudes and latitudes.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame(\n",
    "    {\n",
    "        \"City\": [\"Buenos Aires\", \"Brasilia\", \"Santiago\", \"Bogota\", \"Caracas\"],\n",
    "        \"Country\": [\"Argentina\", \"Brazil\", \"Chile\", \"Colombia\", \"Venezuela\"],\n",
    "        \"Latitude\": [-34.58, -15.78, -33.45, 4.60, 10.48],\n",
    "        \"Longitude\": [-58.66, -47.91, -70.66, -74.08, -66.86],\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A ``GeoDataFrame`` needs a ``shapely`` object. We use geopandas\n",
    "``points_from_xy()`` to transform **Longitude** and **Latitude** into a list\n",
    "of ``shapely.Point`` objects and set it as a ``geometry`` while creating the\n",
    "``GeoDataFrame``. (note that ``points_from_xy()`` is an enhanced wrapper for\n",
    "``[Point(x, y) for x, y in zip(df.Longitude, df.Latitude)]``). The ``crs``\n",
    "value is also set to explicitly state the geometry data defines latitude/\n",
    "longitude world geodetic degree values. This is important for the correct \n",
    "interpretation of the data, such as when plotting with data in other formats."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gdf = geopandas.GeoDataFrame(\n",
    "    df, geometry=geopandas.points_from_xy(df.Longitude, df.Latitude), crs=\"EPSG:4326\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "``gdf`` looks like this :\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(gdf.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we plot the coordinates over a country-level map.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "nbsphinx-thumbnail"
    ]
   },
   "outputs": [],
   "source": [
    "world = geopandas.read_file(get_path(\"naturalearth.land\"))\n",
    "\n",
    "# We restrict to South America.\n",
    "ax = world.clip([-90, -55, -25, 15]).plot(color=\"white\", edgecolor=\"black\")\n",
    "\n",
    "# We can now plot our ``GeoDataFrame``.\n",
    "gdf.plot(ax=ax, color=\"red\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From WKT format\n",
    "===============\n",
    "Here, we consider a ``DataFrame`` having coordinates in WKT format.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame(\n",
    "    {\n",
    "        \"City\": [\"Buenos Aires\", \"Brasilia\", \"Santiago\", \"Bogota\", \"Caracas\"],\n",
    "        \"Country\": [\"Argentina\", \"Brazil\", \"Chile\", \"Colombia\", \"Venezuela\"],\n",
    "        \"Coordinates\": [\n",
    "            \"POINT(-58.66 -34.58)\",\n",
    "            \"POINT(-47.91 -15.78)\",\n",
    "            \"POINT(-70.66 -33.45)\",\n",
    "            \"POINT(-74.08 4.60)\",\n",
    "            \"POINT(-66.86 10.48)\",\n",
    "        ],\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We use ``shapely.wkt`` sub-module to parse wkt format:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from shapely import wkt\n",
    "\n",
    "df[\"Coordinates\"] = geopandas.GeoSeries.from_wkt(df[\"Coordinates\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``GeoDataFrame`` is constructed as follows :\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gdf = geopandas.GeoDataFrame(df, geometry=\"Coordinates\")\n",
    "\n",
    "print(gdf.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, we can plot our ``GeoDataFrame``.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ax = world.clip([-90, -55, -25, 15]).plot(color=\"white\", edgecolor=\"black\")\n",
    "\n",
    "gdf.plot(ax=ax, color=\"red\")\n",
    "\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
